/*
 * File     : Structure.java
 * Created  : 1 May 2011
 *
 * Copyright © 2011 Matthew Wilson (mj. {my-surname} .uk {at} gmail.com)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.googlecode.dni.type.structure;

import com.googlecode.dni.FixedSize;
import com.googlecode.dni.type.NativeObject;


/**
 * <p>
 *  Encapsulates a structure.
 * </p>
 * <h3>Allowable methods</h3>
 * <p>
 *  TODO write out the rules.
 * </p>
 * <h3>Lifetime management</h3>
 * <p>
 *  See the notes on {@link NativeObject} about lifetime management.
 * </p>
 * <p>
 *  Structures may be annotated with a {@link StructureOptions} annotation.
 * </p>
 * <p>
 *  Individual fields may be annotated with various annotations:
 *  {@link FixedSize}, {@link FieldOffset}.  <!-- TODO and the rest -->
 * </p>
 * <p>
 *  Note:  Just because an interface is used does not necessarily mean that
 *  any implementation of the interface may be used in this toolkit.  The
 *  only instances used should be those created by this factory.
 * </p>
 *
 * @author Matthew Wilson
 */
public interface Structure extends NativeObject
{

    /**
     * <p>
     *  Determines if the given object is a structure of the same type and has
     *  the same values as this structure.
     * </p>
     *
     * @return <code>true</code> iff the given object is equal
     */
    @Override
    boolean equals( Object obj );

    /**
     * <p>
     *  Calculates a hash-code based on the structure's fields.
     * </p>
     * <p>
     *  The hash-code algorithm is implementation-, platform-, and
     *  version-dependent.
     * </p>
     *
     * @return a hash-code
     */
    @Override
    int hashCode();

    /**
     * <p>
     *  Renders the structure into a simple string form for debugging, without
     *  performing any memory accesses.
     * </p>
     * <p>
     *  The string format is implementation-, platform-, and
     *  version-dependent.
     * </p>
     *
     * @return a string representation
     */
    @Override
    String toString();

    /**
     * <p>
     *  Renders the structure into a string form for debugging.
     * </p>
     * <p>
     *  The string format is implementation-, platform-, and
     *  version-dependent.  This method will access the memory backed by the
     *  structure; if the structure's memory has been deallocated, this method's
     *  behaviour is undefined.
     * </p>
     *
     * @return a string representation
     */
    String toDebugString();

    /**
     * <p>
     *  Allocates a new structure, copying in the values from this structure.
     * </p>
     * <p>
     *  The new structure behaves as though it were created by a
     *  {@link StructureFactory}, with the same burden of memory management.
     * </p>
     *
     * @return a copy
     *
     * @throws UnsupportedOperationException
     *             if this is an opaque structure
     */
    Structure copy();

    /**
     * <p>
     *  Copies all the values from the given structure into this structure.
     * </p>
     *
     * @param other
     *            the other structure
     *
     * @throws ClassCastException
     *             if the other structure is of a different type
     * @throws UnsupportedOperationException
     *             if this is an opaque structure
     */
    void copyFrom( Structure other );

}
